package com.k2data.k2app.service;

import com.google.common.collect.Maps;
import com.k2data.k2app.common.MyConstant;
import com.k2data.k2app.domain.po.EarlyWaringDO;
import com.k2data.k2app.domain.redis.Login;
import com.k2data.k2app.mapper.EarlyWaringMapper;
import com.k2data.k2app.util.DateFormatterUtil;
import com.k2data.k2app.util.RedisUtils;
import com.k2data.k2app.utils.StringUtils;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * @Author cuilibo@k2data.com.cn
 * @Date 17-12-27 下午2:58.
 */
@Log4j
@Service
public class RedisService {
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private MyConstant myConstant;
    @Autowired
    private EarlyWaringMapper earlyWaringMapper;

    public Object getValue(String key) {
        return redisUtils.getValue(key);
    }

    public void setValue(String key, String value) {
        redisUtils.setValue(key, value);
    }

    public void set(String key, Object value) {
        redisUtils.set(key, value);
    }

    public Map get(String key) {

        return redisUtils.get(key)==null? Maps.newHashMap():(Map)redisUtils.get(key);
    }

    public Set<String> keys(String patten) {

        return redisUtils.keys(patten);
    }

    public void removeKeys(String patten) {
        redisUtils.removePattern(patten);
    }

    public void lpush(String key,Object value) {
        redisUtils.lPush(key,value);
    }

    public List<Object> lrange(String key, long i, long j) {
        return redisUtils.lRange(key,i,j);
    }

    public void add(String key,Object value) {
        redisUtils.add(key,value);
    }

    public void lremove(String key,Object value) {
        redisUtils.lremove(key,value);
    }


    public void logout(Login login) {
        redisUtils.lremove("users",login.getLoginName()+"###"+login.getToken());
    }

    public void updateDeviceStopByTimeOut(){
        System.out.println("check device status!");
        Set<String> keys = keys("*");
        try {
            List devices = deviceService.getDevices();
            for (int i = 0; i < devices.size(); i++) {
                Map device = (Map) devices.get(i);
                String deviceNo = device.getOrDefault("deviceNo", "").toString();
                if(!StringUtils.isEmpty(deviceNo)){
                    if (keys.contains(deviceNo)) {
                        Map map = get(deviceNo);
                        String ts = map.getOrDefault("ts", DateFormatterUtil.getNow()).toString();
                        String status = map.getOrDefault("status", MyConstant.DEVICE_STATUS_HEALTH).toString();

                        Date parse = null;
                        try {
                            parse = new SimpleDateFormat(DateFormatterUtil.timePattern).parse(ts);
                            if (LocalDateTime.now().minusDays(Long.parseLong(myConstant.getOverdueOutline())).isAfter(DateFormatterUtil.UDateToLocalDateTime(parse))) {
                                //myConstant.getOverdueOutline() 没有数据，不在线
                                    map.put("status", MyConstant.DEVICE_STATUS_OUTLINE);
                                    set(deviceNo, map);
                                    try {
//                                        System.out.println("change device status "+deviceNo+" ---"+ts+" ---  "+MyConstant.DEVICE_STATUS_OUTLINE_EN);
                                        if (!status.equals(MyConstant.DEVICE_STATUS_OUTLINE)) {
                                            deviceService.changeStatus(deviceNo, MyConstant.DEVICE_STATUS_OUTLINE);
                                            EarlyWaringDO earlyWaringDO = new EarlyWaringDO();
                                            earlyWaringDO.setDeviceNo(deviceNo);
                                            earlyWaringDO.setLevel(MyConstant.DEVICE_STATUS_OUTLINE);
                                            earlyWaringDO.setMessage("超过"+myConstant.getOverdueOutline()+"天未收到数据，设备状态置为不在线，请管理员及时检查");
                                            earlyWaringDO.setWaringTime(DateFormatterUtil.UDateToLocalDateTime(parse));
                                            earlyWaringDO.setType("real");
                                            earlyWaringDO.setFaultName("实时预警");
                                            earlyWaringDO.setIsMq(1);
//                                            System.out.println("insert a warning! and "+"update device " + deviceNo + " to "+ earlyWaringDO.getLevel());
                                            earlyWaringMapper.insert(earlyWaringDO);
                                        }

                                    } catch (Exception e) {
                                        log.error("update device error!");
                                        e.printStackTrace();
                                    }
                            } else if (LocalDateTime.now().minusMinutes(Long.parseLong(myConstant.getOverdue())).isAfter(DateFormatterUtil.UDateToLocalDateTime(parse))) {
                                    map.put("status", MyConstant.DEVICE_STATUS_STOP);
                                    set(deviceNo, map);
                                    try {
                                        System.out.println("change device status "+deviceNo+" ---"+ts+" ---  "+MyConstant.DEVICE_STATUS_STOP_EN);
                                        if (!status.equals(MyConstant.DEVICE_STATUS_STOP)) {
                                            deviceService.changeStatus(deviceNo, MyConstant.DEVICE_STATUS_STOP);
                                            EarlyWaringDO earlyWaringDO = new EarlyWaringDO();
                                            earlyWaringDO.setDeviceNo(deviceNo);
                                            earlyWaringDO.setLevel(MyConstant.DEVICE_STATUS_STOP);
                                            earlyWaringDO.setMessage("超过"+myConstant.getOverdue()+"分钟未收到数据，设备状态置为停机，请管理员及时检查");
                                            earlyWaringDO.setWaringTime(DateFormatterUtil.UDateToLocalDateTime(parse));
                                            earlyWaringDO.setType("real");
                                            earlyWaringDO.setFaultName("实时预警");
                                            earlyWaringDO.setIsMq(1);
                                            System.out.println("redis no data,insert a warning! and "+"update device " + deviceNo + " to "+ MyConstant.DEVICE_STATUS_STOP_EN);
                                            earlyWaringMapper.insert(earlyWaringDO);
                                        }
                                    } catch (Exception e) {
                                        log.error("update device error!");
                                        e.printStackTrace();
                                    }
                            }
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    } else {
                        Map map = Maps.newHashMap();
                        map.put("status", MyConstant.DEVICE_STATUS_OUTLINE);
                        LocalDateTime initTime = LocalDateTime.of(2016,1,1,0,0,0);
                        map.put("ts", DateFormatterUtil.parseToString(initTime));
                        set(deviceNo, map);
                        try {
                            deviceService.changeStatus(deviceNo, MyConstant.DEVICE_STATUS_OUTLINE);
                        } catch (Exception e) {
                            log.error("update device error!");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("can't not get devices,server is error!");
        }
    }

}
